import React, { useState, useEffect, useMemo, useContext } from 'react';
import {
  Table,
  Button,
  Space,
  Typography,
  Popover,
  Checkbox,
  Notification,
  Breadcrumb,
  Dropdown,
  Menu,
  Card,
} from '@arco-design/web-react';
import {
  IconEdit,
  IconDownload,
  IconFilter,
  IconPlus,
} from '@arco-design/web-react/icon';
import { useHistory } from 'react-router-dom';
import cs from 'classnames';
import useLocale from '@/utils/useLocale';
import SearchForm from './form';
import locale from './locale';
import styles from './style/index.module.less';
import { getColumns } from './constants';
import { Exists, Export, Search } from '@/api/modules/violation';

import { GlobalContext } from '@/context';
import TableEdit from './TableEdit';
import { useDownload } from '@/utils/useDownload';
import ActionWrapper from '@/components/ActionWrapper';
import useIsMountedRef from '@/utils//useIsMountedRef';
import { useSelector } from 'react-redux';
import store from '@/store';

import Violation from '@/assets/Violation.svg';
import { GlobalState } from '@/store';
import useStorageJson from '@/utils/useStorageJson';

import isEmpty from 'lodash/isEmpty';
import debounce from 'lodash/debounce';
import { SorterInfo } from '@arco-design/web-react/es/Table/interface';
const { Title } = Typography;

function SearchTable() {
  const t = useLocale(locale);
  const { rtl, lang } = useContext(GlobalContext);
  const { referenceDetails, actions, userInfo } = useSelector(
    (state: GlobalState) => state
  );

  function requestClipboardPermission() {
    confirm(referenceDetails);
  }

  async function confirm(referenceDetails) {
    if (!referenceDetails.refNumber) {
      return;
    }
    try {
      const { data } = await Exists({ refNumber: referenceDetails.refNumber });
      if (isMountedRef.current && data) {
        Notification.normal({
          id: 'refNumber',
          title: t['confirm.title'] + '：',
          content: `${referenceDetails.refNumber}  ${referenceDetails.fullName}?`,
          duration: 7000,
          btn: (
            <span>
              <Button
                type="secondary"
                size="small"
                onClick={() => Notification.remove('refNumber')}
                style={{ margin: '0 12px' }}
              >
                {t['confirm.cancelText']}
              </Button>
              <Button
                type="primary"
                size="small"
                onClick={() => {
                  Notification.remove('refNumber');
                  history.push({
                    pathname: '/Violation/Detail',
                    search: `?refNumber=${referenceDetails.refNumber}`,
                  });
                }}
              >
                {t['confirm.okText']}
              </Button>
            </span>
          ),
        });
      }
      store.dispatch({
        type: 'update-referenceDetails',
        payload: { referenceDetails: { refNumber: '', fullName: '' } },
      });
    } catch (e) {
      store.dispatch({
        type: 'update-referenceDetails',
        payload: { referenceDetails: { refNumber: '', fullName: '' } },
      });
    }
  }

  useEffect(() => {
    requestClipboardPermission();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const history = useHistory();
  const tableCallback = async (record, type) => {
    if (type === 'details') {
      history.push({
        pathname: '/Violation/Detail',
        search: `?fromPath=violation&refNumber=${record.refNumber}`,
      });
    }
  };

  const [tableColumns, setTableColumns] = useStorageJson(
    `${userInfo.id}_violation_tableColumn`,
    [
      'refNumber',
      'createdAt',
      'violationBoxType',
      'violationType',
      'emirateEntity',
      'violationDesc',
      'violationAdditionalDetails',
      'links',
      'assignedPerson',
      'emirate',
      'source',
      'status',
      'fullName',
      'actionTaken',
      'eid',
      'emirateEntityAr',
    ]
  );
  const [checkList, setCheckList] = useState([]);
  const [visible, setVisible] = useState(false);

  const options = [
    {
      label: t['searchTable.columns.number'],
      value: 'refNumber',
      width: 290,
      disabled: true,
    },
    {
      label: t['searchTable.columns.created'],
      value: 'createdAt',
      width: 200,
    },
    {
      label: t['searchTable.columns.boxType'],
      value: 'violationBoxType',
      width: 200,
    },
    {
      label: t['searchTable.columns.type'],
      value: 'violationType',
      width: 140,
    },
    {
      label: t['searchTable.columns.entityName'],
      value: 'emirateEntity',
      width: 120,
    },
    {
      label: t['searchTable.columns.entityNameAr'],
      value: 'emirateEntityAr',
      width: 120,
    },
    {
      label: t['searchTable.columns.desc'],
      value: 'violationDesc',
      width: 200,
    },
    {
      label: t['searchTable.columns.AdditionalDetails'],
      value: 'violationAdditionalDetails',
      width: 200,
    },
    {
      label: t['searchTable.columns.links'],
      value: 'links',
      width: 240,
    },
    {
      label: t['searchTable.columns.status'],
      value: 'status',
      width: 100,
    },

    {
      label: t['searchTable.columns.taken'],
      value: 'actionTaken',
      width: 140,
    },
    {
      label: t['searchTable.columns.person'],
      value: 'assignedPerson',
      width: 160,
    },
    {
      label: t['searchTable.columns.emirates'],
      value: 'emirate',
      width: 140,
    },
    {
      label: t['searchTable.columns.source'],
      value: 'source',
      width: 100,
    },

    {
      label: t['searchTable.columns.name'],
      value: 'fullName',
      width: 180,
    },
    {
      label: t['searchTable.columns.eid'],
      value: 'eid',
      width: 190,
    },
  ];

  const columns = useMemo(
    () => getColumns(t, tableCallback, tableColumns, options, lang),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [t, tableColumns]
  );

  const width = useMemo(
    () => {
      return columns.reduce((sum, { width = 0 }) => sum + width, 0) || 0;
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [columns]
  );

  const [data, setData] = useState([]);
  const [pagination, setPatination] = useStorageJson(`violation_pagination`, {
    sizeOptions: [10, 20, 50, 100],
    sizeCanChange: true,
    showTotal: true,
    pageSize: 10,
    current: 1,
    pageSizeChangeResetCurrent: true,
  });
  const [loading, setLoading] = useState(false);
  const [formParams, setFormParams] = useStorageJson(
    'violation_formParams',
    {}
  );
  const isMountedRef = useIsMountedRef();
  useEffect(() => {
    fetchData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pagination.current, pagination.pageSize, JSON.stringify(formParams)]);

  async function fetchData() {
    const { current, pageSize } = pagination;
    setLoading(true);
    try {
      const { data } = await Search({
        pageNo: current,
        pageSize,
        ...formParams,
      });

      if (isMountedRef.current) {
        setData(data.data);
        setPatination({
          ...pagination,
          current,
          pageSize,
          total: data.count,
        });
        setLoading(false);
      }
    } catch (e) {
      setLoading(false);
    }
  }

  function onChangeTable({ current, pageSize }, sorter: SorterInfo) {
    const { direction, field } = sorter;
    if (direction) {
      const sort = [];
      const obj = Object.create({});
      if (field == 'emirateEntity' || field == 'emirateEntityAr') {
        obj.field = 'emirate_entity';
      }
      if (field == 'refNumber') {
        obj.field = 'ref_number';
      }
      obj.asc = direction == 'ascend';
      sort.push(obj);
      setFormParams({ ...formParams, sort });
    } else {
      const updatedFormParams = { ...formParams, sort: undefined };
      delete updatedFormParams.sort;
      setFormParams(updatedFormParams);
    }
    setPatination({
      ...pagination,
      current,
      pageSize,
    });
  }

  const handleSearch = debounce((params) => {
    if (params.Date) {
      params.start = params.Date[0];
      params.end = params.Date[1];
    }
    if (loading && isEmpty(params)) return;
    setPatination({ ...pagination, current: 1 });
    setFormParams(params);
  }, 300);

  const CheckboxGroup = Checkbox.Group;

  const onChangeColums = (value) => {
    setTableColumns(value);
  };

  const tableColumnsFilter = () => (
    <CheckboxGroup
      direction="vertical"
      options={options}
      value={tableColumns}
      onChange={onChangeColums}
    />
  );

  async function ExportExcel(e) {
    const params = {
      ...formParams,
      fields: tableColumns,
    };
    await useDownload(
      Export,
      lang === 'ar-EG' ? 'جميع المخالفات' : 'Violation',
      lang === 'ar-EG' ? 'ar' : 'en',
      e,
      e === 1 ? '.csv' : '.xlsx',
      params
    );
  }
  const [selectedRowKeys, setSelectedRowKeys] = useState<
    Array<string | number>
  >([]);

  return (
    <>
      <div className={cs(styles['layout-breadcrumb'], rtl ? 'rtl' : '')}>
        <Breadcrumb>
          <Breadcrumb.Item>
            <Violation
              style={{
                [rtl ? 'marginLeft' : 'marginRight']: '8px',
              }}
              className={cs(
                rtl ? styles['rtl-icon'] : styles.icon,
                'arco-icon'
              )}
            />
            {t['menu.violation']}
          </Breadcrumb.Item>
        </Breadcrumb>
      </div>
      <Card className={styles['page']}>
        {/* <Title heading={6} className={styles['page-title']}>
          {t['searchTable.form.title']}
        </Title> */}
        <SearchForm onSearch={handleSearch} value={formParams} />

        <div className={cs(styles['button-group'], rtl ? 'rtl' : '')}>
          <Space>
            <ActionWrapper action="violation.list.violation/create">
              <Button
                type="primary"
                icon={<IconPlus />}
                onClick={() => {
                  history.push({
                    pathname: `/Violation/Create`,
                  });
                }}
              >
                {t['searchTable.operations.add']}
              </Button>
            </ActionWrapper>
          </Space>
          <Space>
            <ActionWrapper action="violation.list.violation/actions">
              <Button
                type="primary"
                icon={<IconEdit />}
                disabled={checkList.length === 0}
                onClick={() => {
                  if (checkList.length <= 0) {
                    return;
                  }
                  setVisible(!visible);
                }}
              >
                {t['searchTable.operation.edit']}
              </Button>
            </ActionWrapper>
            <Popover
              position="bottom"
              trigger="click"
              content={tableColumnsFilter}
            >
              <Button icon={<IconFilter />}>
                {t['searchTable.operation.filter']}
              </Button>
            </Popover>
            <ActionWrapper action="violation.list.violation/export">
              <Dropdown
                droplist={
                  <Menu>
                    <Menu.Item
                      key="1"
                      className={styles['export-text']}
                      onClick={() => ExportExcel(1)}
                    >
                      CSV
                    </Menu.Item>
                    <Menu.Item
                      key="2"
                      className={styles['export-text']}
                      onClick={() => ExportExcel(2)}
                    >
                      Excel
                    </Menu.Item>
                  </Menu>
                }
                position="bottom"
              >
                <Button type="primary" icon={<IconDownload />}>
                  {t['searchTable.operation.export']}
                </Button>
              </Dropdown>
            </ActionWrapper>
          </Space>
        </div>
        <Table
          rowKey="id"
          hover={true}
          loading={loading}
          onChange={onChangeTable}
          pagination={pagination}
          columns={columns}
          data={data}
          scroll={{
            x: width,
          }}
          border={{
            wrapper: true,
            cell: true,
          }}
          rowSelection={
            actions.includes('violation.list.violation/actions') && {
              fixed: true,
              type: 'checkbox',
              checkAll: true,
              selectedRowKeys,
              onChange: (selectedRowKeys, selectedRows) => {
                setSelectedRowKeys(selectedRowKeys);
                setCheckList(selectedRows);
              },
            }
          }
          rowClassName={(a) => {
            return a?.status?.key;
          }}
        />
        <TableEdit
          visible={visible}
          list={checkList}
          onRefresh={() => {
            fetchData();
          }}
          onVisible={(e) => {
            setSelectedRowKeys([]);
            setCheckList([]);
            setVisible(e);
          }}
        />
      </Card>
    </>
  );
}

export default SearchTable;
